package com.hanthink.framework.config;

import com.hanthink.common.annotation.Anonymous;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 动态解析 @Anonymous 注解，自动放行接口
 *
 * @author WangBin
 * @date 2025-08-20
 */
@Component
public class AnonymousAccessProcessor {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    /**
     * 获取所有被 @Anonymous 标记的接口路径
     */
    public List<String> getAnonymousUrls() {
        return requestMappingHandlerMapping.getHandlerMethods().entrySet().stream()
                .filter(entry -> hasAnonymousAnnotation(entry.getValue()))
                .flatMap(entry -> getPatternsFromRequestMappingInfo(entry.getKey()).stream())
                .collect(Collectors.toList());
    }

    /**
     * 从 RequestMappingInfo 中获取路径模式（兼容新旧版本）
     */
    private List<String> getPatternsFromRequestMappingInfo(RequestMappingInfo info) {
        List<String> patterns = new ArrayList<>();

        // 尝试使用新的 PathPatterns API（Spring Boot 3+）
        if (info.getPathPatternsCondition() != null) {
            patterns.addAll(info.getPathPatternsCondition().getPatterns().stream()
                    .map(pattern -> pattern.getPatternString())
                    .collect(Collectors.toList()));
        }
        // 回退到旧的 Patterns API（Spring Boot 2.x）
        else if (info.getPatternsCondition() != null) {
            patterns.addAll(info.getPatternsCondition().getPatterns());
        }

        return patterns;
    }

    /**
     * 检查方法或类是否有 @Anonymous 注解
     */
    private boolean hasAnonymousAnnotation(HandlerMethod handlerMethod) {
        return handlerMethod.getMethodAnnotation(Anonymous.class) != null
                || handlerMethod.getBeanType().getAnnotation(Anonymous.class) != null;
    }

    /**
     * 加强版 - 获取所有匿名URL（包含HTTP方法信息）
     */
    public List<String> getAnonymousUrl() {
        return requestMappingHandlerMapping.getHandlerMethods().entrySet().stream()
                .filter(entry -> hasAnonymousAnnotation(entry.getValue()))
                .flatMap(entry -> {
                    RequestMappingInfo info = entry.getKey();
                    return getPatternsFromRequestMappingInfo(info).stream()
                            .map(pattern -> {
                                if (!pattern.startsWith("/")) {
                                    return "/" + pattern;
                                }
                                return pattern;
                            });
                })
                .distinct()
                .collect(Collectors.toList());
    }
}
